home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / resolv / res_debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-28  |  17.4 KB  |  779 lines

  1. /*
  2.  * ++Copyright++ 1985, 1990, 1993
  3.  * -
  4.  * Copyright (c) 1985, 1990, 1993
  5.  *    The Regents of the University of California.  All rights reserved.
  6.  * 
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *     This product includes software developed by the University of
  18.  *     California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  * 
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. static char sccsid[] = "@(#)res_debug.c    8.1 (Berkeley) 6/4/93";
  58. static char rcsid[] = "$Id: res_debug.c,v 1.2 1994/07/28 21:56:22 roland Exp $";
  59. #endif /* LIBC_SCCS and not lint */
  60.  
  61. #include <sys/param.h>
  62. #include <netinet/in.h>
  63. #include <arpa/inet.h>
  64. #include <arpa/nameser.h>
  65.  
  66. #include <stdio.h>
  67. #include <resolv.h>
  68. #if defined(BSD) && (BSD >= 199103)
  69. # include <string.h>
  70. #else
  71. # include "../conf/portability.h"
  72. #endif
  73.  
  74. #if defined(USE_OPTIONS_H)
  75. # include "../conf/options.h"
  76. #endif
  77.  
  78. const char *_res_opcodes[] = {
  79.     "QUERY",
  80.     "IQUERY",
  81.     "CQUERYM",
  82.     "CQUERYU",
  83.     "4",
  84.     "5",
  85.     "6",
  86.     "7",
  87.     "8",
  88.     "UPDATEA",
  89.     "UPDATED",
  90.     "UPDATEDA",
  91.     "UPDATEM",
  92.     "UPDATEMA",
  93.     "ZONEINIT",
  94.     "ZONEREF",
  95. };
  96.  
  97. const char *_res_resultcodes[] = {
  98.     "NOERROR",
  99.     "FORMERR",
  100.     "SERVFAIL",
  101.     "NXDOMAIN",
  102.     "NOTIMP",
  103.     "REFUSED",
  104.     "6",
  105.     "7",
  106.     "8",
  107.     "9",
  108.     "10",
  109.     "11",
  110.     "12",
  111.     "13",
  112.     "14",
  113.     "NOCHANGE",
  114. };
  115.  
  116. static char retbuf[16];
  117.  
  118. static const char *
  119. dewks(wks)
  120.     int wks;
  121. {
  122.     switch (wks) {
  123.     case 5: return "rje";
  124.     case 7: return "echo";
  125.     case 9: return "discard";
  126.     case 11: return "systat";
  127.     case 13: return "daytime";
  128.     case 15: return "netstat";
  129.     case 17: return "qotd";
  130.     case 19: return "chargen";
  131.     case 20: return "ftp-data";
  132.     case 21: return "ftp";
  133.     case 23: return "telnet";
  134.     case 25: return "smtp";
  135.     case 37: return "time";
  136.     case 39: return "rlp";
  137.     case 42: return "name";
  138.     case 43: return "whois";
  139.     case 53: return "domain";
  140.     case 57: return "apts";
  141.     case 59: return "apfs";
  142.     case 67: return "bootps";
  143.     case 68: return "bootpc";
  144.     case 69: return "tftp";
  145.     case 77: return "rje";
  146.     case 79: return "finger";
  147.     case 87: return "link";
  148.     case 95: return "supdup";
  149.     case 100: return "newacct";
  150.     case 101: return "hostnames";
  151.     case 102: return "iso-tsap";
  152.     case 103: return "x400";
  153.     case 104: return "x400-snd";
  154.     case 105: return "csnet-ns";
  155.     case 109: return "pop-2";
  156.     case 111: return "sunrpc";
  157.     case 113: return "auth";
  158.     case 115: return "sftp";
  159.     case 117: return "uucp-path";
  160.     case 119: return "nntp";
  161.     case 121: return "erpc";
  162.     case 123: return "ntp";
  163.     case 133: return "statsrv";
  164.     case 136: return "profile";
  165.     case 144: return "NeWS";
  166.     case 161: return "snmp";
  167.     case 162: return "snmp-trap";
  168.     case 170: return "print-srv";
  169.     default: (void) sprintf(retbuf, "%d", wks); return (retbuf);
  170.     }
  171. }
  172.  
  173. static const char *
  174. deproto(protonum)
  175.     int protonum;
  176. {
  177.     switch (protonum) {
  178.     case 1: return "icmp";
  179.     case 2: return "igmp";
  180.     case 3: return "ggp";
  181.     case 5: return "st";
  182.     case 6: return "tcp";
  183.     case 7: return "ucl";
  184.     case 8: return "egp";
  185.     case 9: return "igp";
  186.     case 11: return "nvp-II";
  187.     case 12: return "pup";
  188.     case 16: return "chaos";
  189.     case 17: return "udp";
  190.     default: (void) sprintf(retbuf, "%d", protonum); return (retbuf);
  191.     }
  192. }
  193.  
  194. static const u_char *
  195. do_rrset(msg, cp, cnt, pflag, file, hs)
  196.     int cnt, pflag;
  197.     const u_char *cp, *msg;
  198.     const char *hs;
  199.     FILE *file;
  200. {
  201.     int n;
  202.     int sflag;
  203.  
  204.     /*
  205.      * Print answer records.
  206.      */
  207.     sflag = (_res.pfcode & pflag);
  208.     if (n = ntohs(cnt)) {
  209.         if ((!_res.pfcode) ||
  210.             ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
  211.             fprintf(file, hs);
  212.         while (--n >= 0) {
  213.             cp = p_rr(cp, msg, file);
  214.             if ((cp - msg) > PACKETSZ)
  215.                 return (NULL);
  216.         }
  217.         if ((!_res.pfcode) ||
  218.             ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
  219.             putc('\n', file);
  220.     }
  221.     return (cp);
  222. }
  223.  
  224. void
  225. __p_query(msg)
  226.     const u_char *msg;
  227. {
  228.     __fp_query(msg, stdout);
  229. }
  230.  
  231. #ifdef ultrix
  232. /* ultrix 4.0's packaging has some icky packaging.  alias for it here.
  233.  * there is more junk of this kind over in res_comp.c.
  234.  */
  235. void
  236. p_query(msg)
  237.     const u_char *msg;
  238. {
  239.     __p_query(msg);
  240. }
  241. #endif
  242.  
  243. /*
  244.  * Print the current options.
  245.  * This is intended to be primarily a debugging routine.
  246.  */
  247. void
  248. __fp_resstat(statp, file)
  249.     struct __res_state *statp;
  250.     FILE *file;
  251. {
  252.     register u_long mask;
  253.  
  254.     fprintf(file, ";; res options:");
  255.     if (!statp)
  256.         statp = &_res;
  257.     for (mask = 1;  mask != 0;  mask <<= 1)
  258.         if (statp->options & mask)
  259.             fprintf(file, " %s", p_option(mask));
  260.     putc('\n', file);
  261. }
  262.  
  263. /*
  264.  * Print the contents of a query.
  265.  * This is intended to be primarily a debugging routine.
  266.  */
  267. void
  268. __fp_nquery(msg, len, file)
  269.     const u_char *msg;
  270.     int len;
  271.     FILE *file;
  272. {
  273.     register const u_char *cp, *endMark;
  274.     register const HEADER *hp;
  275.     register int n;
  276.  
  277. #define TruncTest(x) if (x >= endMark) goto trunc
  278. #define    ErrorTest(x) if (x == NULL) goto error
  279.  
  280.     /*
  281.      * Print header fields.
  282.      */
  283.     hp = (HEADER *)msg;
  284.     cp = msg + HFIXEDSZ;
  285.     endMark = cp + len;
  286.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
  287.         fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
  288.             _res_opcodes[hp->opcode],
  289.             _res_resultcodes[hp->rcode],
  290.             ntohs(hp->id));
  291.         putc('\n', file);
  292.     }
  293.     putc(';', file);
  294.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
  295.         fprintf(file,"; flags:");
  296.         if (hp->qr)
  297.             fprintf(file, " qr");
  298.         if (hp->aa)
  299.             fprintf(file, " aa");
  300.         if (hp->tc)
  301.             fprintf(file, " tc");
  302.         if (hp->rd)
  303.             fprintf(file, " rd");
  304.         if (hp->ra)
  305.             fprintf(file, " ra");
  306.         if (hp->pr)
  307.             fprintf(file, " pr");
  308.     }
  309.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
  310.         fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
  311.         fprintf(file, ", Ans: %d", ntohs(hp->ancount));
  312.         fprintf(file, ", Auth: %d", ntohs(hp->nscount));
  313.         fprintf(file, ", Addit: %d", ntohs(hp->arcount));
  314.     }
  315.     if ((!_res.pfcode) || (_res.pfcode & 
  316.         (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
  317.         putc('\n',file);
  318.     }
  319.     /*
  320.      * Print question records.
  321.      */
  322.     if (n = ntohs(hp->qdcount)) {
  323.         if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  324.             fprintf(file,";; QUESTIONS:\n");
  325.         while (--n >= 0) {
  326.             fprintf(file,";;\t");
  327.             TruncTest(cp);
  328.             cp = p_cdname(cp, msg, file);
  329.             ErrorTest(cp);
  330.             TruncTest(cp);
  331.             if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  332.                 fprintf(file, ", type = %s",
  333.                     __p_type(_getshort((u_char*)cp)));
  334.             cp += INT16SZ;
  335.             TruncTest(cp);
  336.             if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  337.                 fprintf(file, ", class = %s\n",
  338.                     __p_class(_getshort((u_char*)cp)));
  339.             cp += INT16SZ;
  340.             putc('\n', file);
  341.         }
  342.     }
  343.     /*
  344.      * Print authoritative answer records
  345.      */
  346.     TruncTest(cp);
  347.     cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
  348.               ";; ANSWERS:\n");
  349.     ErrorTest(cp);
  350.  
  351.     /*
  352.      * print name server records
  353.      */
  354.     TruncTest(cp);
  355.     cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
  356.               ";; AUTHORITY RECORDS:\n");
  357.     ErrorTest(cp);
  358.  
  359.     TruncTest(cp);
  360.     /*
  361.      * print additional records
  362.      */
  363.     cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file,
  364.               ";; ADDITIONAL RECORDS:\n");
  365.     ErrorTest(cp);
  366.     return;
  367.  trunc:
  368.     fprintf(file, "\n;; ...truncated\n");
  369.     return;
  370.  error:
  371.     fprintf(file, "\n;; ...malformed\n");
  372. }
  373.  
  374. void
  375. __fp_query(msg, file)
  376.     const u_char *msg;
  377.     FILE *file;
  378. {
  379.     fp_nquery(msg, PACKETSZ, file);
  380. }
  381.  
  382. const u_char *
  383. __p_cdnname(cp, msg, len, file)
  384.     const u_char *cp, *msg;
  385.     int len;
  386.     FILE *file;
  387. {
  388.     char name[MAXDNAME];
  389.     int n;
  390.  
  391.     if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
  392.         return (NULL);
  393.     if (name[0] == '\0')
  394.         putc('.', file);
  395.     else
  396.         fputs(name, file);
  397.     return (cp + n);
  398. }
  399.  
  400. const u_char *
  401. __p_cdname(cp, msg, file)
  402.     const u_char *cp, *msg;
  403.     FILE *file;
  404. {
  405.     return (p_cdnname(cp, msg, PACKETSZ, file));
  406. }
  407.  
  408. /* XXX:    the rest of these functions need to become length-limited, too. (vix)
  409.  */
  410.  
  411. const u_char *
  412. __p_fqname(cp, msg, file)
  413.     const u_char *cp, *msg;
  414.     FILE *file;
  415. {
  416.     char name[MAXDNAME];
  417.     int n, len;
  418.  
  419.     if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
  420.         return (NULL);
  421.     if (name[0] == '\0') {
  422.         putc('.', file);
  423.     } else {
  424.         fputs(name, file);
  425.         if (name[strlen(name) - 1] != '.')
  426.             putc('.', file);
  427.     }
  428.     return (cp + n);
  429. }
  430.  
  431. /*
  432.  * Print resource record fields in human readable form.
  433.  */
  434. const u_char *
  435. __p_rr(cp, msg, file)
  436.     const u_char *cp, *msg;
  437.     FILE *file;
  438. {
  439.     int type, class, dlen, n, c;
  440.     struct in_addr inaddr;
  441.     const u_char *cp1, *cp2;
  442.     u_int32_t tmpttl, t;
  443.     int lcnt;
  444.  
  445.     if ((cp = p_fqname(cp, msg, file)) == NULL)
  446.         return (NULL);            /* compression error */
  447.     type = _getshort((u_char*)cp);
  448.     cp += INT16SZ;
  449.     class = _getshort((u_char*)cp);
  450.     cp += INT16SZ;
  451.     tmpttl = _getlong((u_char*)cp);
  452.     cp += INT32SZ;
  453.     dlen = _getshort((u_char*)cp);
  454.     cp += INT16SZ;
  455.     cp1 = cp;
  456.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
  457.         fprintf(file, "\t%lu", tmpttl);
  458.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
  459.         fprintf(file, "\t%s", __p_class(class));
  460.     fprintf(file, "\t%s", __p_type(type));
  461.     /*
  462.      * Print type specific data, if appropriate
  463.      */
  464.     switch (type) {
  465.     case T_A:
  466.         switch (class) {
  467.         case C_IN:
  468.         case C_HS:
  469.             bcopy(cp, (char *)&inaddr, INADDRSZ);
  470.             if (dlen == 4) {
  471.                 fprintf(file,"\t%s", inet_ntoa(inaddr));
  472.                 cp += dlen;
  473.             } else if (dlen == 7) {
  474.                 char *address;
  475.                 u_char protocol;
  476.                 u_short port;
  477.  
  478.                 address = inet_ntoa(inaddr);
  479.                 cp += INADDRSZ;
  480.                 protocol = *(u_char*)cp;
  481.                 cp += sizeof(u_char);
  482.                 port = _getshort((u_char*)cp);
  483.                 cp += INT16SZ;
  484.                 fprintf(file, "\t%s\t; proto %d, port %d",
  485.                     address, protocol, port);
  486.             }
  487.             break;
  488.         default:
  489.             cp += dlen;
  490.         }
  491.         break;
  492.     case T_CNAME:
  493.     case T_MB:
  494.     case T_MG:
  495.     case T_MR:
  496.     case T_NS:
  497.     case T_PTR:
  498.         putc('\t', file);
  499.         cp = p_fqname(cp, msg, file);
  500.         break;
  501.  
  502.     case T_HINFO:
  503.     case T_ISDN:
  504.         if (n = *cp++) {
  505.             fprintf(file,"\t%.*s", n, cp);
  506.             cp += n;
  507.         }
  508.         if (n = *cp++) {
  509.             fprintf(file,"\t%.*s", n, cp);
  510.             cp += n;
  511.         }
  512.         break;
  513.  
  514.     case T_SOA:
  515.         putc('\t', file);
  516.         cp = p_fqname(cp, msg, file);    /* origin */
  517.         putc(' ', file);
  518.         cp = p_fqname(cp, msg, file);    /* mail addr */
  519.         fputs(" (\n", file);
  520.         t = _getlong((u_char*)cp);  cp += INT32SZ;
  521.         fprintf(file,"\t\t\t%lu\t; serial\n", t);
  522.         t = _getlong((u_char*)cp);  cp += INT32SZ;
  523.         fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
  524.         t = _getlong((u_char*)cp);  cp += INT32SZ;
  525.         fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
  526.         t = _getlong((u_char*)cp);  cp += INT32SZ;
  527.         fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
  528.         t = _getlong((u_char*)cp);  cp += INT32SZ;
  529.         fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
  530.         break;
  531.  
  532.     case T_MX:
  533.     case T_AFSDB:
  534.     case T_RT:
  535.         fprintf(file,"\t%d ", _getshort((u_char*)cp));
  536.         cp += INT16SZ;
  537.         cp = p_fqname(cp, msg, file);
  538.         break;
  539.  
  540.       case T_TXT:
  541.     case T_X25:
  542.         (void) fputs("\t\"", file);
  543.         cp2 = cp1 + dlen;
  544.         while (cp < cp2) {
  545.             if (n = (unsigned char) *cp++) {
  546.                 for (c = n; c > 0 && cp < cp2; c--)
  547.                     if (*cp == '\n') {
  548.                         (void) putc('\\', file);
  549.                         (void) putc(*cp++, file);
  550.                     } else
  551.                         (void) putc(*cp++, file);
  552.             }
  553.         }
  554.         putc('"', file);
  555.           break;
  556.  
  557.       case T_NSAP:
  558.         (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
  559.         cp += dlen;
  560.           break;
  561.  
  562.     case T_MINFO:
  563.     case T_RP:
  564.         putc('\t', file);
  565.         cp = p_fqname(cp, msg, file);
  566.         putc(' ', file);
  567.         cp = p_fqname(cp, msg, file);
  568.         break;
  569.  
  570.     case T_UINFO:
  571.         putc('\t', file);
  572.         fputs((char *)cp, file);
  573.         cp += dlen;
  574.         break;
  575.  
  576.     case T_UID:
  577.     case T_GID:
  578.         if (dlen == 4) {
  579.             fprintf(file,"\t%u", _getlong((u_char*)cp));
  580.             cp += INT32SZ;
  581.         }
  582.         break;
  583.  
  584.     case T_WKS:
  585.         if (dlen < INT32SZ + 1)
  586.             break;
  587.         bcopy(cp, (char *)&inaddr, INADDRSZ);
  588.         cp += INT32SZ;
  589.         fprintf(file, "\t%s %s ( ",
  590.             inet_ntoa(inaddr),
  591.             deproto((int) *cp));
  592.         cp += sizeof(u_char);
  593.         n = 0;
  594.         lcnt = 0;
  595.         while (cp < cp1 + dlen) {
  596.             c = *cp++;
  597.             do {
  598.                  if (c & 0200) {
  599.                     if (lcnt == 0) {
  600.                         fputs("\n\t\t\t", file);
  601.                         lcnt = 5;
  602.                     }
  603.                     fputs(dewks(n), file);
  604.                     putc(' ', file);
  605.                     lcnt--;
  606.                 }
  607.                  c <<= 1;
  608.             } while (++n & 07);
  609.         }
  610.         putc(')', file);
  611.         break;
  612.  
  613. #ifdef ALLOW_T_UNSPEC
  614.     case T_UNSPEC:
  615.         {
  616.             int NumBytes = 8;
  617.             u_char *DataPtr;
  618.             int i;
  619.  
  620.             if (dlen < NumBytes) NumBytes = dlen;
  621.             fprintf(file, "\tFirst %d bytes of hex data:",
  622.                 NumBytes);
  623.             for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
  624.                 fprintf(file, " %x", *DataPtr);
  625.             cp += dlen;
  626.         }
  627.         break;
  628. #endif /* ALLOW_T_UNSPEC */
  629.  
  630.     default:
  631.         fprintf(file,"\t?%d?", type);
  632.         cp += dlen;
  633.     }
  634. #if 0
  635.     fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
  636. #else
  637.     putc('\n', file);
  638. #endif
  639.     if (cp - cp1 != dlen) {
  640.         fprintf(file,";; packet size error (found %d, dlen was %d)\n",
  641.             cp - cp1, dlen);
  642.         cp = NULL;
  643.     }
  644.     return (cp);
  645. }
  646.  
  647. static    char nbuf[40];
  648.  
  649. /*
  650.  * Return a string for the type
  651.  */
  652. const char *
  653. __p_type(type)
  654.     int type;
  655. {
  656.     switch (type) {
  657.     case T_A:    return "A";
  658.     case T_NS:    return "NS";
  659.     case T_CNAME:    return "CNAME";
  660.     case T_SOA:    return "SOA";
  661.     case T_MB:    return "MB";
  662.     case T_MG:    return "MG";
  663.     case T_MR:    return "MR";
  664.     case T_NULL:    return "NULL";
  665.     case T_WKS:    return "WKS";
  666.     case T_PTR:    return "PTR";
  667.     case T_HINFO:    return "HINFO";
  668.     case T_MINFO:    return "MINFO";
  669.     case T_MX:    return "MX";
  670.     case T_TXT:    return "TXT";
  671.     case T_NSAP:    return "NSAP";
  672.     case T_RP:    return "RP";
  673.     case T_AFSDB:    return "AFSDB";
  674.     case T_X25:    return "X25";
  675.     case T_ISDN:    return "ISDN";
  676.     case T_RT:    return "RT";
  677.     case T_AXFR:    return "AXFR";
  678.     case T_MAILB:    return "MAILB";
  679.     case T_MAILA:    return "MAILA";
  680.     case T_ANY:    return "ANY";
  681.     case T_UINFO:    return "UINFO";
  682.     case T_UID:    return "UID";
  683.     case T_GID:    return "GID";
  684. #ifdef ALLOW_T_UNSPEC
  685.     case T_UNSPEC:    return "UNSPEC";
  686. #endif /* ALLOW_T_UNSPEC */
  687.     default:    (void)sprintf(nbuf, "%d", type); return (nbuf);
  688.     }
  689. }
  690.  
  691. /*
  692.  * Return a mnemonic for class
  693.  */
  694. const char *
  695. __p_class(class)
  696.     int class;
  697. {
  698.     switch (class) {
  699.     case C_IN:    return("IN");
  700.     case C_HS:    return("HS");
  701.     case C_ANY:    return("ANY");
  702.     default:    (void)sprintf(nbuf, "%d", class); return (nbuf);
  703.     }
  704. }
  705.  
  706. /*
  707.  * Return a mnemonic for an option
  708.  */
  709. const char *
  710. __p_option(option)
  711.     u_long option;
  712. {
  713.     switch (option) {
  714.     case RES_INIT:        return "init";
  715.     case RES_DEBUG:        return "debug";
  716.     case RES_AAONLY:    return "aaonly";
  717.     case RES_USEVC:        return "usevc";
  718.     case RES_PRIMARY:    return "primry";
  719.     case RES_IGNTC:        return "igntc";
  720.     case RES_RECURSE:    return "recurs";
  721.     case RES_DEFNAMES:    return "defnam";
  722.     case RES_STAYOPEN:    return "styopn";
  723.     case RES_DNSRCH:    return "dnsrch";
  724.     case RES_INSECURE1:    return "insecure1";
  725.     case RES_INSECURE2:    return "insecure2";
  726.     default:        sprintf(nbuf, "?0x%x?", option); return nbuf;
  727.     }
  728. }
  729.  
  730. /*
  731.  * Return a mnemonic for a time to live
  732.  */
  733. char *
  734. __p_time(value)
  735.     u_int32_t value;
  736. {
  737.     int secs, mins, hours, days;
  738.     register char *p;
  739.  
  740.     if (value == 0) {
  741.         strcpy(nbuf, "0 secs");
  742.         return (nbuf);
  743.     }
  744.  
  745.     secs = value % 60;
  746.     value /= 60;
  747.     mins = value % 60;
  748.     value /= 60;
  749.     hours = value % 24;
  750.     value /= 24;
  751.     days = value;
  752.     value = 0;
  753.  
  754. #define    PLURALIZE(x)    x, (x == 1) ? "" : "s"
  755.     p = nbuf;
  756.     if (days) {
  757.         (void)sprintf(p, "%d day%s", PLURALIZE(days));
  758.         while (*++p);
  759.     }
  760.     if (hours) {
  761.         if (days)
  762.             *p++ = ' ';
  763.         (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
  764.         while (*++p);
  765.     }
  766.     if (mins) {
  767.         if (days || hours)
  768.             *p++ = ' ';
  769.         (void)sprintf(p, "%d min%s", PLURALIZE(mins));
  770.         while (*++p);
  771.     }
  772.     if (secs || ! (days || hours || mins)) {
  773.         if (days || hours || mins)
  774.             *p++ = ' ';
  775.         (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
  776.     }
  777.     return (nbuf);
  778. }
  779.